﻿#include "Widget.h"
#include "ui_Widget.h"

#include "winsock.h"

#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->lineEdit->setText("127.0.0.1");
    ui->lineEdit_2->setText("6379");

    _isConnect = false;
    _ctx = NULL;
    _reply = NULL;
}

Widget::~Widget()
{
    delete ui;
}

void Widget::addLog(int nType, QString str)
{
    // 设置当前行要使用的背景颜色
    QColor color;
    switch(nType)
    {
    case INFO_LOG:
        color = QColor(175, 255, 175);
        break;
    case ERROR_LOG:
        color = QColor(255, 100, 100);
        break;
    case OUTPUT_LOG:
        color = QColor(Qt::cyan);
        break;
    default:
        break;
    }
    ui->textEdit->setTextBackgroundColor(color);

    ui->textEdit->append(str);

    // 恢复原来的颜色
    ui->textEdit->setTextBackgroundColor(Qt::white);
}

void Widget::addCommandLog(QString str)
{
    ui->textEdit->setTextBackgroundColor(Qt::yellow);

    ui->textEdit->append(QString::fromLocal8Bit("执行命令> ") + str);

    ui->textEdit->setTextBackgroundColor(Qt::white);
}

bool Widget::tryConnect()
{
    if (!_isConnect)
        on_pushButton_clicked();

    if (!_isConnect)
        addLog(ERROR_LOG, QString::fromLocal8Bit("尚未连接到 Redis 服务！"));

    return _isConnect;
}

void Widget::on_pushButton_clicked()
{
    struct timeval timeout = { 1, 500000 }; // 1.5 seconds
    _ctx = redisConnectWithTimeout(ui->lineEdit->text().toLocal8Bit().data(),
                                   ui->lineEdit_2->text().toInt(),
                                   timeout);
    if (_ctx == NULL || _ctx->err)
    {
        if (_ctx)
        {
            addLog(ERROR_LOG, QString::fromLocal8Bit("连接 Redis 服务失败：%1").arg(_ctx->errstr));
            redisFree(_ctx);
        }
        else
        {
            addLog(ERROR_LOG, QString::fromLocal8Bit("连接 Redis 服务失败：分配 Redis 上下文失败！"));
        }
    }
    else
    {
        addLog(INFO_LOG, QString::fromLocal8Bit("连接 Redis 服务成功..."));
        _isConnect = true;
    }
}

void Widget::on_pushButton_9_clicked()
{
    if (_ctx)
        redisFree(_ctx);
    _isConnect = false;
    addLog(INFO_LOG, QString::fromLocal8Bit("已与 Redis 服务断开连接..."));
}

// PING
void Widget::on_pushButton_2_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog("PING");
    _reply = (redisReply*)redisCommand(_ctx, "PING");
    addLog(OUTPUT_LOG, QString::fromLocal8Bit(_reply->str));
    freeReplyObject(_reply);
}

// SET
void Widget::on_pushButton_3_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog(QString("SET %1 '%2'").arg("test1").arg("This is test1"));
    _reply = (redisReply*)redisCommand(_ctx, "SET %s %s", "test1", "This is test1");
    addLog(OUTPUT_LOG, QString::fromLocal8Bit(_reply->str));
    freeReplyObject(_reply);
}

// SET(binary safe)
void Widget::on_pushButton_4_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog(QString("SET %1 '%2'").arg("test2").arg("This is test2"));
    _reply = (redisReply*)redisCommand(_ctx, "SET %b %b", "test2", (size_t)5, "This is test2", (size_t)13);
    addLog(OUTPUT_LOG, QString::fromLocal8Bit(_reply->str));
    freeReplyObject(_reply);
}

// GET
void Widget::on_pushButton_5_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog("GET test1");
    _reply = (redisReply*)redisCommand(_ctx, "GET test1");
    addLog(OUTPUT_LOG, QString::fromLocal8Bit(_reply->str));
    freeReplyObject(_reply);
}

// INCR
void Widget::on_pushButton_6_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog("INCR test3");
    _reply = (redisReply*)redisCommand(_ctx, "INCR test3");
    addLog(OUTPUT_LOG, QString::number(_reply->integer));
    freeReplyObject(_reply);
}

// LPUSH
void Widget::on_pushButton_7_clicked()
{
    if (!tryConnect())
        return;

    char buf[64];
    char log[256];
    for (int i = 0; i < 10; i++)
    {
        sprintf(log, "LPUSH test4 element-%d", i);
        addCommandLog(log);

        sprintf(buf, "%d", i);
        _reply = (redisReply*)redisCommand(_ctx, "LPUSH test4 element-%s", buf);
        addLog(OUTPUT_LOG, QString::number(_reply->integer));
        freeReplyObject(_reply);
    }
}

// LRANGE
void Widget::on_pushButton_8_clicked()
{
    if (!tryConnect())
        return;

    addCommandLog("LRANGE test4 0 9");
    _reply = (redisReply*)redisCommand(_ctx, "LRANGE test4 0 9");
    if (_reply->type == REDIS_REPLY_ARRAY)
    {
        for (int i = 0; i < _reply->elements; i++)
        {
            addLog(OUTPUT_LOG, QString::number(i) + ") " + QString::fromLocal8Bit(_reply->element[i]->str));
        }
    }
    freeReplyObject(_reply);
}
